#include "TurboAlloc.hpp"
// ntimes 一轮申请和释放内存的次数
// nworks 线程数
// rounds 轮次
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks); // 线程池
    // std::atomic<size_t> malloc_costtime = 0;//原子操作 将size_t类型设置成原子的
    // std::atomic<size_t> free_costtime=0;//C++20之前会判定为函数删除错误
    std::atomic<size_t> malloc_costtime{0}; // 原子操作 将size_t类型设置成原子的
    std::atomic<size_t> free_costtime{0};

    for(size_t k=0;k<nworks;++k)
    {
        //vthread[k]表示vthread向量容器中第k+1个元素
        //将新创建的线程对象赋给vthread容器中第k+1个元素
        //将一个特定的任务关联到容器的这个位置上，以便后续对这个线程进行管理
        vthread[k]=std::thread([&,k]{
            std::vector<void*>v;
            v.reserve(ntimes);
            for(size_t j=0;j<rounds;j++)
            {
                size_t begin1=clock();
                for(size_t i=0;i<ntimes;i++)
                {
                    v.push_back(malloc(16));
                }
                size_t end1=clock();
                // 申请的时间消耗
                size_t begin2=clock();
                for(size_t i=0;i<ntimes;i++)
                {
                    free(v[i]);
                }
                size_t end2=clock();
                v.clear();
                malloc_costtime+=(end1-begin1);
                free_costtime+=(end2-begin2);
            }
        });
    }
    for(auto&t:vthread)
    {
        t.join();
    }
    printf("%zu个线程并发执行%zu轮次，每轮次malloc：%zu次 花费：%zu ms\n",
        nworks,rounds,ntimes,(size_t)malloc_costtime);
    printf("%zu个线程并发执行%zu轮次，每轮次free：%zu次 花费：%zu ms\n",
        nworks,rounds,ntimes,(size_t)free_costtime);
    printf("%zu个线程并发malloc&free %zu轮次，总计花费：%zu ms\n",
        nworks,nworks*rounds*ntimes,(size_t)(malloc_costtime+free_costtime));
}
void BenchmarkTurboAlloc(size_t ntimes, size_t nworks, size_t rounds)
{
    std::vector<std::thread> vthread(nworks); // 线程池
    // std::atomic<size_t> malloc_costtime = 0;//原子操作 将size_t类型设置成原子的
    // std::atomic<size_t> free_costtime=0;//C++20之前会判定为函数删除错误
    std::atomic<size_t> malloc_costtime{0}; // 原子操作 将size_t类型设置成原子的
    std::atomic<size_t> free_costtime{0};

    for(size_t k=0;k<nworks;++k)
    {
        //vthread[k]表示vthread向量容器中第k+1个元素
        //将新创建的线程对象赋给vthread容器中第k+1个元素
        //将一个特定的任务关联到容器的这个位置上，以便后续对这个线程进行管理
        vthread[k]=std::thread([&,k]{
            std::vector<void*>v;
            v.reserve(ntimes);
            for(size_t j=0;j<rounds;j++)
            {
                size_t begin1=clock();
                for(size_t i=0;i<ntimes;i++)
                {
                    v.push_back(TurboAlloc(16));
                }
                size_t end1=clock();
                // 申请的时间消耗
                size_t begin2=clock();
                for(size_t i=0;i<ntimes;i++)
                {
                    TurboFree(v[i]);
                }
                size_t end2=clock();
                v.clear();
                malloc_costtime+=(end1-begin1);
                free_costtime+=(end2-begin2);
            }
        });
    }
    for(auto&t:vthread)
    {
        t.join();
    }
    printf("%zu个线程并发执行%zu轮次，每轮次malloc：%zu次 花费：%zu ms\n",
        nworks,rounds,ntimes,(size_t)malloc_costtime);
    printf("%zu个线程并发执行%zu轮次，每轮次free：%zu次 花费：%zu ms\n",
        nworks,rounds,ntimes,(size_t)free_costtime);
    printf("%zu个线程并发malloc&free %zu轮次，总计花费：%zu ms\n",
        nworks,nworks*rounds*ntimes,(size_t)(malloc_costtime+free_costtime));
}

// int main()
// {
//     size_t n=100000;
//     cout<<"==============================================="<<endl;
//     // BenchmarkMalloc(n,4,10);
//     cout<<endl<<endl;
//     BenchmarkTurboAlloc(n,4,10);
//     cout<<"==============================================="<<endl;
//     return 0;
// }